package exp3;

import java.util.Stack;

public class Calculator {
    public static void main(String[] args) {
        String str = "(3+5)*7";
        System.out.println(evaluateInfixExpression(str));
    }

    public static int evaluateInfixExpression(String expression) {
        Stack<Integer> values = new Stack<>();
        Stack<Character> operators = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (Character.isDigit(c)) {
                StringBuilder num = new StringBuilder();
                while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                    num.append(expression.charAt(i));
                    i++;
                }
                i--;
                values.push(Integer.parseInt(num.toString()));
            } else if (c == '(') {
                operators.push(c);
            } else if (c == ')') {
                while (!operators.isEmpty() && operators.peek() != '(') {
                    calculate(values, operators);
                }
                operators.pop();
            } else if (isOperator(c)) {
                while (!operators.isEmpty() && youXianJi(operators.peek()) >= youXianJi(c)) {
                    calculate(values, operators);
                }
                operators.push(c);
            }
        }
        while (!operators.isEmpty()) {
            calculate(values, operators);
        }
        return values.pop();
    }

    private static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    private static int youXianJi(char c) {
        if (c == '+' || c == '-') {
            return 1;
        } else if (c == '*' || c == '/') {
            return 2;
        }
        return 0;
    }

    private static void calculate(Stack<Integer> values, Stack<Character> operators) {
        char operator = operators.pop();
        int v1 = values.pop();
        int v2 = values.pop();
        int result = -1;
        try {
            result = performOperation(v1, v2, operator);
        } catch (Exception e) {
            System.err.println("An error occurred: " + e.getMessage());
        }
        values.push(result);
    }

    private static int performOperation(int a, int b, char operator) throws Exception {
        return switch (operator) {
            case '+' -> a + b;
            case '-' -> a - b;
            case '*' -> a * b;
            case '/' -> {
                if (b == 0) {
                    throw new Exception("Division by zero");
                }
                yield a / b;
            }
            default -> throw new Exception("Invalid operator: " + operator);
        };
    }
}
